package com.zxf.basic.expand

import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.ForegroundColorSpan
import android.util.Log
import androidx.annotation.ColorInt
import net.sourceforge.pinyin4j.PinyinHelper
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType
import java.math.BigDecimal
import java.math.RoundingMode
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.util.*

fun String?.plusSpace(content: String?): String {
    return this.plus(" ").plus(content)
}

private const val RANGE_MIN = 19968 // \u4e00
private const val RANGE_MAX = 171941 // \u9fa5

/**
 * 返回字符串的 大写首字母
 */
val String.getFirstEnChar: Char
    get() {
        if (this.isNotEmpty()) {
            val nameChar = this[0]
            val defaultFormat = HanyuPinyinOutputFormat()
            defaultFormat.caseType = HanyuPinyinCaseType.UPPERCASE
            defaultFormat.toneType = HanyuPinyinToneType.WITHOUT_TONE
            if (nameChar.toInt() in RANGE_MIN..RANGE_MAX) {
                try {
                    return PinyinHelper.toHanyuPinyinStringArray(nameChar, defaultFormat)[0][0]
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            } else if (nameChar.toString().matches("[A-Z]".toRegex()) || nameChar.toString().matches("[a-z]".toRegex())) {
                return Character.toUpperCase(nameChar)
            }
        }
        return '#'
    }

/**
 * 获取拼音
 */
val String.getEn: String
    get() {
        val format = HanyuPinyinOutputFormat()
        format.toneType = HanyuPinyinToneType.WITHOUT_TONE
        format.caseType = HanyuPinyinCaseType.LOWERCASE
        val chars = this.trim().toCharArray()
        if (chars.isEmpty()) return ""
        try {
            val buffer = StringBuffer()
            chars.forEach {
                if (it.toInt() in RANGE_MIN..RANGE_MAX) {
                    //  中文字符
                    val strings = PinyinHelper.toHanyuPinyinStringArray(it, format)
                    if (strings.isNotEmpty()) {
                        buffer.append(strings[0])
                    }
                } else {
                    // 其他字符
                    buffer.append(it)
                }
            }
            return buffer.toString()
        } catch (e: Exception) {
            return ""
        }
    }

/**
 * 格式化成 10000.00  2位小数 不四舍五入
 */
fun String.decimalFormatDigits2Floor(): String {
    if (this.isEmpty() || this == "0" || this == "0." || this == ".") return "0.00"
    val df = DecimalFormat("##0.00", DecimalFormatSymbols.getInstance(Locale.CHINA))
    df.roundingMode = RoundingMode.FLOOR
    return try {
        df.format(BigDecimal(this).toDouble())
    } catch (e: Exception) {
        this
    }
}

fun String.toPoint8(): String {
    var result = this
    val index = indexOf(".")
    if (index > 0) {
        val num = substring(index + 1)
        for (i in 0..(7 - num.length)) {
            result = result.plus("0")
        }
    } else {
        result.plus(".00000000")
    }
    return this
}

/**
 * 格式化成 整数位用逗号隔开，小数位有就显示，没有就不显示，多余的0不显示
 */
fun String?.decimalFormatComma(): String {
    if (this.isNullOrEmpty() || this == "0" || this == "0." || this == ".") return "0"
    val df = DecimalFormat("###,##0.########", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).toDouble())
    } catch (e: Exception) {
        this
    }
}

// 整数用千位分隔符隔开
fun String.thousandsSeparate(scale: Int = 8): String {
    if (startsWith(".")) return "0".plus(this)
    if (startsWith("0") && !contains(".") && length > 1) return substring(1)
    val after = substringAfter(".", "")
    if (toDouble() < 1000 && after.length < scale) return this
    val df = DecimalFormat("###,##0.########", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        // 末尾是否带小数点
        val endWithDot = endsWith(".")
        // 是否是有小数点且后面带0
        val haveDotAndEndWithZero = contains(".") && endsWith("0")
        // 包含小数点
        val haveDot = contains(".")
        // 以 .0 结尾
        var level = 0
        if (haveDotAndEndWithZero) {
            when {
                endsWith(".0") -> level = 1
                endsWith(".00") -> level = 2
                endsWith(".000") -> level = 3
                endsWith(".0000") -> level = 4
                endsWith(".00000") -> level = 5
                endsWith(".000000") -> level = 6
                endsWith(".0000000") -> level = 7
                endsWith(".00000000") -> level = 8
            }
        }
        val s = df.format(BigDecimal(this).setScale(scale, RoundingMode.DOWN))
        if (endWithDot) {
            s.plus(".")
        } else {
            if (haveDotAndEndWithZero) {
                var str = when (level) {
                    1 -> s.plus(".0")
                    2 -> s.plus(".00")
                    3 -> s.plus(".000")
                    4 -> s.plus(".0000")
                    5 -> s.plus(".00000")
                    6 -> s.plus(".000000")
                    7 -> s.plus(".0000000")
                    8 -> s.plus(".00000000")
                    else -> {
                        // 有小数点 0结尾
                        // 如果小数点位数没有超出限制，
                        if (s.substringAfter(".").length < scale)
                            s.plus("0")
                        else
                            s
                    }
                }
                // 判断补了0后，小数位是否超过小数位限制，超过就去除多余的0
                val afterLength = str.substringAfter(".").length
                if (afterLength > scale) {
                    val d = afterLength - scale
                    str = str.substring(0, str.length - d)
                }
                str
            } else if (haveDot && after.length > scale && !s.contains(".")) {
                // 如果原始值有小数点 后面都是0，除了最后一位不是0，且刚好超过小数位限制， 这样经过格式化后会不包含小数    1.001  2位
                s.plus(".").plus(after.substring(0, scale))
            } else
                s
        }
    } catch (e: Exception) {
        this
    }
}

/**
 * 去掉千分位分隔符
 */
fun String.replaceThousandsSeparate(): String {
    return this.replace(",", "")
}

/**
 * 格式化成 小数位有就显示，没有就不显示，多余的0不显示
 */
fun String.decimalFormatDigits(): String {
    if (this.isEmpty() || this == "0" || this == "0." || this == ".") return "0"
    val df = DecimalFormat("#####0.########", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).toDouble())
    } catch (e: Exception) {
        this
    }
}

/**
 * 格式化成 小数位有就显示，没有就不显示，多余的0不显示
 */
fun String.decimalFormat2Digits(): String {
    if (this.isEmpty() || this == "0" || this == "0." || this == ".") return "0"
    val df = DecimalFormat("#####0.##", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).toDouble())
    } catch (e: Exception) {
        this
    }
}

/**
 * 格式化成 10000.0000  4位小数
 */
fun String.decimalFormatDigits4(): String {
    if (this.isEmpty() || this == "0" || this == "0." || this == ".") return "0.0000"
    val df = DecimalFormat("##0.0000", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).toDouble())
    } catch (e: Exception) {
        this
    }
}

fun String?.decimalTripTrailingZeros4(): String {
    if (this.isNullOrEmpty() || this == "0" || this == "0." || this == ".") return "0"
    val df = DecimalFormat("##0.####", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).toDouble())
    } catch (e: Exception) {
        this
    }
}

fun String?.decimalFormatIntegral(): String {
    if (this.isNullOrEmpty() || this == "0" || this == "0." || this == ".") return "0"
    val df = DecimalFormat("##0.#####", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).toDouble())
    } catch (e: Exception) {
        this
    }
}

fun String.decimalFormatDigits2(roundingMode: Int = BigDecimal.ROUND_HALF_UP): String {
    if (this.isEmpty() || this == "0" || this == "0." || this == ".") return "0"
    val df = DecimalFormat("##0.##", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).setScale(2, roundingMode).toDouble())
    } catch (e: Exception) {
        this
    }
}

fun String.decimalFormatDigits8(roundingMode: Int = BigDecimal.ROUND_HALF_UP): String {
    if (this.isEmpty() || this == "0" || this == "0." || this == ".") return "0"
    val df = DecimalFormat("##0.########", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).setScale(8, roundingMode).toDouble())
    } catch (e: Exception) {
        this
    }
}


fun String.decimalFormatDigitsN(scale: Int = 0, roundingMode: Int = BigDecimal.ROUND_HALF_UP): String {
    if (this.isEmpty() || this == "0" || this == "0." || this == ".") return "0"
    val df = DecimalFormat("##0.##", DecimalFormatSymbols.getInstance(Locale.CHINA))
    return try {
        df.format(BigDecimal(this).setScale(scale, roundingMode).toDouble())
    } catch (e: Exception) {
        this
    }
}

/**
 * 格式化成 10000.0000  4位小数 不四舍五入
 */
fun String.decimalFormatDigits4Floor(): String {
    if (this.isEmpty() || this == "0" || this == "0." || this == ".") return "0.0000"
    val df = DecimalFormat("##0.0000", DecimalFormatSymbols.getInstance(Locale.CHINA))
    df.roundingMode = RoundingMode.FLOOR
    return try {
        df.format(BigDecimal(this).toDouble())
    } catch (e: Exception) {
        this
    }
}


/**
 * 去掉后面多余的0
 */
fun String?.stripTrailingZeros(): String {
    if (this.isNullOrEmpty() || this == "0." || this == "." || this == "0.0") return "0"
    return BigDecimal(this).stripTrailingZeros().toPlainString()
}

/**
 *科学计数法转String
 */
fun String.scientificToString(): String {
    if (this.isEmpty() || this == "0." || this == ".") return "0.00"
    return BigDecimal(this).toPlainString()
}


fun String.plusNewline(content: String): String {
    return this.plus("\n").plus(content)
}

/**
 * 四舍五入 有效位后面的数字直接进位
 */
fun String.decimalFormatDigitsUp(scale: Int): String {
    return BigDecimal(this).setScale(scale, BigDecimal.ROUND_UP).toPlainString()
}

/**
 * 四舍五入 有效位后面的数字直接退位
 */
fun String.decimalFormatDigitsDown(scale: Int): String {
    return BigDecimal(this).setScale(scale, BigDecimal.ROUND_DOWN).toPlainString()
}

fun String.zeroFill(): String {
    try {
        val digit = this.toInt()
        return if (digit < 10) {
            "0$digit"
        } else {
            this
        }
    } catch (e: NumberFormatException) {
        e.printStackTrace()
    }
    return "0"
}

fun String?.orZero() = this.or("0")

fun String?.or(str: String?): String {
    return if (this.isNullOrEmpty()) {
        str.orEmpty()
    } else {
        this
    }
}

fun CharSequence?.isZeroOrEmpty(): Boolean {
    return isNullOrEmpty() || this == "0"
}

/**
 * 末尾空一格
 */
fun String.appendSpace(): String = this.plus(" ")

fun String.divide(divisor: String, scale: Int = 2, roundingMode: Int = BigDecimal.ROUND_HALF_UP): String {
    if (this.isEmpty() || divisor.isEmpty()) {
        return ""
    }
    val b1 = BigDecimal(this.dotReplaceComma())
    val b2 = BigDecimal(divisor.dotReplaceComma())
    return b1.divide(b2, scale, roundingMode).toString()
}

fun String?.toNumber(default: String = "0", f: Int = 4): String {
    val formatted = if (f == 2) this?.decimalFormatDigits2() else if (f == 4) this?.decimalFormatDigits4() else this?.decimalFormatDigits8()
    val self = formatted?.replace(",", "")
    return if (self.isEmpty() || this == "." || this == "0.") default else self.orEmpty()
}

fun String?.toPercent(): String {
    val percent = BigDecimal(this?.orZero()).multiply(BigDecimal(100)).toString().decimalFormatDigits2()
    return percent.plus("%")
}

fun String.dotReplaceComma(): String {

    return if (this.contains(",")) {
        this.replace(",", ".")
    } else {
        this
    }
}

fun String.dump(str: String): String {
    return replace(str, "")
}

fun String.logD(tag: String = "") {
    Log.d(tag, this)
}

fun String.logE(tag: String = "") {
    Log.d(tag, this)
}

fun String.tmEmail() : String {
    if (isEmpty() || length < 2) {
       return this
    }
    val index = indexOf("@")
    if (index == -1) {
        return this
    }
    return substring(0, index/2) + "***" + substring(index)
}

fun String.replaceSlash(): String {
    replace("\\/", "/")
    return this
}

fun String.subLength(l: Int): String {
    if (length > l)
        return substring(0, l)
    return this
}

@Throws(java.lang.Exception::class)
fun String.spannableTextColor(keyWorld: String, @ColorInt color: Int): SpannableStringBuilder {
    val span = SpannableStringBuilder(this)
    if (this.contains(keyWorld)) {
        val startIndex = this.indexOf(keyWorld)
        val endIndex = startIndex + keyWorld.length
        try {
            span.setSpan(ForegroundColorSpan(color), startIndex, endIndex, Spannable.SPAN_EXCLUSIVE_INCLUSIVE)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    return span
}


